use std::io::prelude::*;
use std::{fs::File, io::SeekFrom};

use actix_web::{get, http::header, web, HttpRequest, HttpResponse, Responder};
use log::debug;
use percent_encoding::percent_decode;

#[test]
fn test() {
    let s = "";
    let n: i32 = if s.is_empty() { 0 } else { s.parse().unwrap() };
    println!("n: {}", n);
}

#[get("/video/{video}")]
pub async fn video(req: HttpRequest, video: web::Path<String>) -> impl Responder {
    debug!("video path: {}", video);
    let path_src = percent_decode(video.as_bytes())
        .decode_utf8()
        .unwrap()
        .into_owned();
    let mut f = File::open(path_src).unwrap();

    let file_size = f.metadata().unwrap().len();
    let headers = req.headers();
    let range = headers.get("Range").unwrap().to_str().ok();
    if let Some(content_range) = range {
        debug!("content_range: {}", content_range);
        let parts = content_range.replace("bytes=", "");
        let parts: Vec<_> = parts.split("-").collect();
        let start: u64 = parts[0].parse().unwrap();
        let mut end: u64 = if parts[1].is_empty() {
            (start + 1000000) as u64
        } else {
            parts[1].parse().unwrap()
        };

        if end > file_size - 1 {
            end = file_size - 1;
        }

        debug!("start: {}, end: {}", start, end);

        let mut buffer: Vec<u8> = Vec::new();

        f.seek(SeekFrom::Start(start)).unwrap();
        let mut handler = f.take(end - start + 1);
        let size_r = handler.read_to_end(buffer.as_mut()).unwrap();

        debug!("size_r: {}", size_r);

        HttpResponse::PartialContent()
            .header(
                header::CONTENT_RANGE,
                format!("bytes {}-{}/{}", start, end, file_size),
            )
            .header(header::ACCEPT_RANGES, "bytes")
            .header(header::CONTENT_LENGTH, file_size)
            .header(header::CONTENT_TYPE, "video/mp4")
            .body(buffer)
    } else {
        let mut buffer: Vec<u8> = Vec::new();
        f.read_to_end(buffer.as_mut()).unwrap();

        HttpResponse::Ok()
            .header(header::CONTENT_LENGTH, file_size)
            .header(header::CONTENT_TYPE, "video/mp4")
            .body(buffer)
    }
}
